import 'dart:math';
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart' as vector;

class FloatingParticlesEffect extends StatefulWidget {
  final Color baseColor;
  final int particleCount;
  final int clusterCount;
  final double width;
  final double height;
  final double minParticleSize;
  final double maxParticleSize;
  final bool enableBlur;
  final double minSpeed;
  final double maxSpeed;
  final double diffusionFactor;
  final double spiralTightness;    // 新增：螺旋紧密度
  final double interClusterAttractionFactor;  // 新增：簇间引力系数
  
  const FloatingParticlesEffect({
    super.key,
    required this.baseColor,
    this.particleCount = 100,
    this.clusterCount = 5,
    required this.width,
    required this.height,
    this.minParticleSize = 2.0,
    this.maxParticleSize = 5.0,
    this.enableBlur = false,
    this.minSpeed = 1.0,
    this.maxSpeed = 2.0,
    this.diffusionFactor = 0.15,
    this.spiralTightness = 0.8,    // 默认螺旋紧密度
    this.interClusterAttractionFactor = 0.3,  // 默认簇间引力
  });

  @override
  State<FloatingParticlesEffect> createState() => _FloatingParticlesEffectState();
}

class _FloatingParticlesEffectState extends State<FloatingParticlesEffect> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late List<Particle> _particles;
  late List<ClusterCenter> _clusterCenters;
  final Random _random = Random();
  double _time = 0;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 10),
    )..repeat();
    
    _initializeParticles();
  }

  void _initializeParticles() {
    _particles = [];
    _clusterCenters = [];
    final particlesPerCluster = widget.particleCount ~/ widget.clusterCount;
    
    // 初始化簇中心
    for (int c = 0; c < widget.clusterCount; c++) {
      final angle = 2 * math.pi * c / widget.clusterCount;
      _clusterCenters.add(ClusterCenter(
        position: Offset(
          widget.width / 2,
          widget.height + _random.nextDouble() * 50,
        ),
        baseAngle: angle,
        phase: _random.nextDouble() * 2 * math.pi,
      ));
    }
    
    // 初始化粒子
    for (int c = 0; c < widget.clusterCount; c++) {
      final clusterCenter = _clusterCenters[c];
      for (int i = 0; i < particlesPerCluster; i++) {
        final radius = _random.nextDouble() * (widget.width * 0.4);  // 增加初始分布半径
        final angle = _random.nextDouble() * 2 * math.pi;
        final offset = Offset(
          math.cos(angle) * radius,
          math.sin(angle) * radius,
        );
        
        _particles.add(Particle(
          position: clusterCenter.position + offset,
          velocity: vector.Vector3(0, -widget.minSpeed - _random.nextDouble() * (widget.maxSpeed - widget.minSpeed), 0),
          size: widget.minParticleSize + _random.nextDouble() * (widget.maxParticleSize - widget.minParticleSize),
          opacity: 0.3 + _random.nextDouble() * 0.7,
          noiseOffset: _random.nextDouble() * 1000,
          clusterId: c,
        ));
      }
    }
  }

  double _noise(double x, double y, double time) {
    final t = time * 0.3;
    return math.sin(x * 0.05 + t) * math.cos(y * 0.05 + t) * 0.5;
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        _updateParticles();
        return CustomPaint(
          size: Size(widget.width, widget.height),
          painter: ParticlesPainter(
            particles: _particles,
            baseColor: widget.baseColor,
            enableBlur: widget.enableBlur,
          ),
        );
      },
    );
  }

  void _updateParticles() {
    _time += 0.016;
    
    // 更新簇中心
    for (int i = 0; i < _clusterCenters.length; i++) {
      final center = _clusterCenters[i];
      center.phase += 0.02 * widget.spiralTightness;
      
      // 计算螺旋运动，随高度增加螺旋半径
      final heightRatio = (center.position.dy / widget.height);  // 越往上螺旋半径越大
      final spiralRadius = widget.width * 0.3 * (1 + (1 - heightRatio) * 0.5);  // 增加基础半径并随高度扩大
      final angle = center.baseAngle + center.phase;
      
      // 更新簇中心位置
      center.position = Offset(
        widget.width / 2 + math.cos(angle) * spiralRadius,
        center.position.dy + (-widget.minSpeed - 0.5),
      );
      
      // 如果簇中心到达顶部，重置到底部
      if (center.position.dy < -10) {
        center.position = Offset(
          widget.width / 2 + (_random.nextDouble() - 0.5) * widget.width * 0.5,  // 随机水平位置
          widget.height + _random.nextDouble() * 50,
        );
      }
    }
    
    // 更新粒子
    for (final particle in _particles) {
      final clusterCenter = _clusterCenters[particle.clusterId];
      final heightRatio = particle.position.dy / widget.height;
      
      // 计算噪声扰动，随高度增加扰动
      final noiseFactor = 1 + (1 - heightRatio) * 2;  // 越往上扰动越大
      final noiseX = _noise(particle.position.dx + particle.noiseOffset, particle.position.dy, _time) * noiseFactor;
      final noiseY = _noise(particle.position.dy + particle.noiseOffset, particle.position.dx, _time) * noiseFactor;
      
      // 计算到簇中心的引力，随高度减弱
      final toCenter = clusterCenter.position - particle.position;
      final distanceToCenter = toCenter.distance;
      final attractionForce = toCenter / distanceToCenter * widget.interClusterAttractionFactor * heightRatio;  // 越往上引力越小
      
      // 更新位置
      particle.position = Offset(
        particle.position.dx + particle.velocity.x + noiseX * widget.diffusionFactor + attractionForce.dx,
        particle.position.dy + particle.velocity.y + noiseY * widget.diffusionFactor + attractionForce.dy,
      );
      
      // 如果粒子飞出视图，重置到对应簇的底部
      if (particle.position.dy < -10) {
        final radius = _random.nextDouble() * (widget.width * 0.4);  // 增加重生时的分布半径
        final angle = _random.nextDouble() * 2 * math.pi;
        particle.position = Offset(
          clusterCenter.position.dx + math.cos(angle) * radius,
          widget.height + _random.nextDouble() * 50,
        );
        particle.velocity = vector.Vector3(
          0,
          -widget.minSpeed - _random.nextDouble() * (widget.maxSpeed - widget.minSpeed),
          0,
        );
        particle.opacity = 0.3 + _random.nextDouble() * 0.7;
      }
      
      // 渐变透明度
      particle.opacity *= 0.997;
    }
  }
}

class ClusterCenter {
  Offset position;
  final double baseAngle;
  double phase;
  
  ClusterCenter({
    required this.position,
    required this.baseAngle,
    required this.phase,
  });
}

class Particle {
  Offset position;
  vector.Vector3 velocity;
  double size;
  double opacity;
  double noiseOffset;
  int clusterId;
  
  Particle({
    required this.position,
    required this.velocity,
    required this.size,
    required this.opacity,
    required this.noiseOffset,
    required this.clusterId,
  });
}

class ParticlesPainter extends CustomPainter {
  final List<Particle> particles;
  final Color baseColor;
  final bool enableBlur;

  ParticlesPainter({
    required this.particles,
    required this.baseColor,
    required this.enableBlur,
  });

  @override
  void paint(Canvas canvas, Size size) {
    for (final particle in particles) {
      final paint = Paint()
        ..color = baseColor.withOpacity(particle.opacity)
        ..style = PaintingStyle.fill;
      
      if (enableBlur) {
        paint.maskFilter = const MaskFilter.blur(BlurStyle.normal, 2);
      }

      // 添加深度效果
      final depthFactor = (particle.position.dy / size.height);
      final adjustedSize = particle.size * (1 + depthFactor * 0.5);
      
      canvas.drawCircle(
        particle.position,
        adjustedSize,
        paint,
      );
    }
  }

  @override
  bool shouldRepaint(ParticlesPainter oldDelegate) => true;
} 